package com.jason.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.jasonj1102.aesspringbootstarter.utils.AesUtils;
import com.jason.system.common.ResultEntity;
import com.jason.system.common.util.JwtUtil;
import com.jason.system.common.util.RedisUtil;
import com.jason.system.entity.User;
import com.jason.system.service.UserService;
import io.swagger.annotations.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author jie
 * @version 1.0
 * success come from self-discipline
 * @date 2021/3/24 20:39
 */
@RestController
@RequestMapping("/api/user")
@Api(value = "/user",tags = "用户登录接口")
public class UserController {

  private static final Logger logger = LoggerFactory.getLogger(UserController.class);

  @Autowired
  private UserService userService;

  @Autowired
  private AesUtils aesUtils;

  @Autowired
  private RedisUtil redisUtil;

  @Value(value = "${myProperties.p1}")
  private String p1;

  private Subject getSubject(){
    return SecurityUtils.getSubject();
  }

  @ApiOperation(value ="登录",notes = "用户登录")
  @ApiImplicitParams(
          {@ApiImplicitParam(paramType ="query", name = "username", value = "用户名", required = true, dataType = "String"),
                  @ApiImplicitParam(paramType ="query", name = "password", value = "密码", required = true, dataType = "String")}
  )
  @ApiResponses({
          @ApiResponse(code = 200, message = "登录成功"),
          @ApiResponse(code = 201,message = "密码错误"),
          @ApiResponse(code = 401,message = "用户不存在")
  })
  @PostMapping("/login")
  public JSONObject login( User loginUser){
    logger.info("==>>>UserController==>>>进入路径：/api/user/login.....");
    JSONObject jsonObject = new JSONObject();
    Map<String,Object> resMap = new HashMap<>(8);
    User user = userService.getUserByName(loginUser.getUsername());
    resMap.put("user",user);
    logger.info("==>>>UserController==>>>最终获取user对象：{}",user);
    ResultEntity r = new ResultEntity();
    if(user == null){
      r.setCode(401);
      r.setMessage("用户不存在");
    }else {
      try {
        if(!user.getPassword().equals(aesUtils.encrypt(loginUser.getPassword()))){
          r.setCode(201);
          r.setMessage("密码错误");
        }else {
          r.setCode(200);
          r.setMessage("登录成功");
          //登录成功，生成token
          String token = JwtUtil.createToken(user);
          resMap.put("token",token);
          logger.info("==>>>UserController==>>>生成用户token: {}",token);
          r.setData(resMap);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    jsonObject.put("result",r);
    return jsonObject;
  }

  @ApiOperation(value ="注册",notes = "用户注册")
  @ApiImplicitParams(
          {@ApiImplicitParam(paramType ="query", name = "username", value = "用户名", required = true, dataType = "String"),
                  @ApiImplicitParam(paramType ="query", name = "password", value = "密码", required = true, dataType = "String")}
  )
  @RequiresRoles("role:root")
  @PostMapping("/register")
  public JSONObject register(User registerUser){
    logger.info("==>>>UserController==>>>进入路径：/api/user/register.....");
    JSONObject jsonObject = new JSONObject();
    ResultEntity r = new ResultEntity();
    User user = userService.getUserByName(registerUser.getUsername());
    logger.info("==>>>UserController==>>>最终获取user对象：{}",user);
    if(user!=null){
      r.setCode(401);
      r.setMessage("用户名已存在");
    }else {
      r.setCode(200);
      r.setMessage("注册成功");
      userService.register(registerUser);
    }
    jsonObject.put("result",r);
    return jsonObject;
  }

  @ApiOperation(value = "退出系统",notes = "用户登出")
  @ApiResponses({
          @ApiResponse(code = 200,message = "退出成功"),
          @ApiResponse(code = 201,message = "退出失败")
  })
  @PostMapping("/logout")
  public JSONObject logout(){
    logger.info("==>>>UserController==>>>进入路径：/api/user/logout.....");
    JSONObject jsonObject = new JSONObject();
    ResultEntity r = new ResultEntity();
    Subject subject = getSubject();
    try {
      logger.info("==>>>UserController==>>>Subject执行登出操作.....");
      if (subject.isAuthenticated()){
        subject.logout();
      }
      r.setData(200);
      r.setMessage("退出成功");
      logger.info("==>>>UserController==>>>Subject执行登出操作成功.....");
    }catch (Exception e){
      logger.info("==>>>UserController==>>>Subject执行登出操作失败.....");
      r.setData(201);
      r.setMessage("退出失败");
    }
    jsonObject.put("result",r);
    return jsonObject;
  }

  @ApiOperation(value ="修改密码",notes = "用户修改密码")
  @ApiImplicitParams(
          {@ApiImplicitParam(paramType ="query", name = "uId", value = "用户id", required = true, dataType = "Integer"),
                  @ApiImplicitParam(paramType ="query", name = "password", value = "密码", required = true, dataType = "String")
                  ,@ApiImplicitParam(paramType = "query",name = "username",value = "验证token合法性的用户名",required = true,dataType="String")}
  )
  @ApiResponses({
          @ApiResponse(code = 200,message = "修改密码成功"),
          @ApiResponse(code = 201,message = "修改密码失败"),
          @ApiResponse(code = 201,message = "用户没有权限修改密码")
  })
  @PostMapping("/updatePassword")
  @RequiresRoles("role:root")
  public JSONObject updatePassword(@RequestParam("uId") Integer uId ,@RequestParam("password") String password){
    Subject subject = getSubject();
    logger.info("==>>>UserController==>>>进入路径：/api/user/updatePassword.....");
    JSONObject jsonObject = new JSONObject();
    ResultEntity r = new ResultEntity();
    if (!subject.isPermitted(p1)){
      logger.info("==>>>UserController==>>>该用户没有权限修改密码.....");
      r.setCode(202);
      r.setMessage("该用户没有权限修改密码");
    }else {
      logger.info("==>>>UserController==>>>正在更新密码中.....");
      try {
        userService.updatePassword(uId,password);
        logger.info("==>>>UserController==>>>更新密码完成.....");
        r.setCode(200);
        r.setMessage("修改密码成功");
      }catch (Exception e){
        logger.info("==>>>UserController==>>>更新密码失败.....");
        r.setCode(201);
        r.setMessage("修改密码失败");
      }
    }
    jsonObject.put("result",r);
    return jsonObject;
  }

  @PostMapping("/delete/{uId}")
  public JSONObject register(@PathVariable("uId") Integer uId){
    logger.info("==>>>UserController==>>>进入路径：/api/user/delete.....");
    JSONObject jsonObject = new JSONObject();
    ResultEntity r = new ResultEntity();
    logger.info("==>>>UserController==>>>正在删除user信息中.....");
    boolean result =userService.deleteUserById(uId);
    if (result){
      logger.info("==>>>UserController==>>>删除user信息完成.....");
      r.setCode(200);
      r.setMessage("删除user信息成功");
    }else {
      logger.info("==>>>UserController==>>>删除删除user信息失败.....");
      r.setCode(201);
      r.setMessage("删除user信息失败");
    }
    jsonObject.put("result",r);
    return jsonObject;
  }

}
